package project.sample.nio;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
import java.util.Iterator;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

/**
 * @author: WUZH009
 * @date: 2019/8/23 14:00
 **/
public class NioHttpServerContainer {

    private ThreadPoolExecutor bossGroup;

    private ThreadPoolExecutor workerGroup;

    private int port;

    public NioHttpServerContainer(int port) {
        this.port = port;
        init();
    }

    public void init() {
        workerGroup = new ThreadPoolExecutor(20, 100, Long.MAX_VALUE, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<>(200), new ThreadPoolExecutor.DiscardPolicy());
        bossGroup = new ThreadPoolExecutor(5, 20, Long.MAX_VALUE, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<>(20), new ThreadPoolExecutor.DiscardPolicy());
    }

    public void open() {
        try {
            Selector selector = Selector.open();
            ServerSocketChannel channel = ServerSocketChannel.open();
            channel.socket().bind(new InetSocketAddress(port));
            channel.configureBlocking(false);
            channel.register(selector, SelectionKey.OP_ACCEPT);
            while (true) {
                if (selector.select() == 0) {
                    continue;
                }
                Iterator<SelectionKey> iterator = selector.selectedKeys().iterator();
                while (iterator.hasNext()) {
                    SelectionKey key = iterator.next();
                    iterator.remove();
                    if (!key.isValid()) {
                        continue;
                    }
                    if (key.isAcceptable()) {
                        System.out.println("client 连入");
                        SocketChannel socketChannel = ((ServerSocketChannel) key.channel()).accept();
                        socketChannel.configureBlocking(false);
                        socketChannel.register(key.selector(), SelectionKey.OP_READ);
                    } else if (key.isReadable()) {
                        workerGroup.submit(new NioWorkerThread(key));
//                        new NioWorkerThread(key).call();
                    }
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public static void main(String[] args) {
        new NioHttpServerContainer(8890).open();
    }


}
